const PriorityQueue = require("../template")

function testPriorityQueueCustomComparator() {
  console.log(
    "1. 最大堆测试:",
    (() => {
      const maxPq = new PriorityQueue((a, b) => b - a) // 最大堆
      
      maxPq.enqueue(10)
      maxPq.enqueue(5)
      maxPq.enqueue(15)
      maxPq.enqueue(3)
      maxPq.enqueue(8)
      
      const max = maxPq.dequeue()
      const secondMax = maxPq.peek()
      
      return max === 15 &&
             secondMax === 10 &&
             maxPq.isValid() === true &&
             maxPq.size() === 4
    })()
  )

  console.log(
    "2. 字符串优先级测试:",
    (() => {
      const stringPq = new PriorityQueue((a, b) => a.localeCompare(b)) // 字典序
      
      stringPq.enqueue("banana")
      stringPq.enqueue("apple")
      stringPq.enqueue("cherry")
      stringPq.enqueue("date")
      
      const first = stringPq.dequeue()
      const second = stringPq.peek()
      
      return first === "apple" &&
             second === "banana" &&
             stringPq.isValid() === true &&
             stringPq.size() === 3
    })()
  )

  console.log(
    "3. 对象优先级测试:",
    (() => {
      const objectPq = new PriorityQueue((a, b) => a.priority - b.priority)
      
      objectPq.enqueue({ name: "task1", priority: 3 })
      objectPq.enqueue({ name: "task2", priority: 1 })
      objectPq.enqueue({ name: "task3", priority: 2 })
      objectPq.enqueue({ name: "task4", priority: 4 })
      
      const first = objectPq.dequeue()
      const second = objectPq.peek()
      
      return first.name === "task2" &&
             first.priority === 1 &&
             second.name === "task3" &&
             second.priority === 2 &&
             objectPq.isValid() === true &&
             objectPq.size() === 3
    })()
  )

  console.log(
    "4. 自定义比较函数测试:",
    (() => {
      const customPq = new PriorityQueue((a, b) => {
        // 自定义比较：偶数优先，然后按值大小
        if (a % 2 === 0 && b % 2 !== 0) return -1
        if (a % 2 !== 0 && b % 2 === 0) return 1
        return a - b
      })
      
      customPq.enqueue(5)
      customPq.enqueue(2)
      customPq.enqueue(7)
      customPq.enqueue(4)
      customPq.enqueue(1)
      
      const first = customPq.dequeue()
      const second = customPq.dequeue()
      const third = customPq.peek()
      
      return first === 2 && // 偶数优先
             second === 4 && // 偶数优先
             third === 1 && // 然后是奇数
             customPq.isValid() === true &&
             customPq.size() === 3
    })()
  )

  console.log(
    "5. 反向比较器测试:",
    (() => {
      const reversePq = new PriorityQueue((a, b) => b - a) // 反向比较
      
      reversePq.enqueue(1)
      reversePq.enqueue(5)
      reversePq.enqueue(3)
      reversePq.enqueue(9)
      reversePq.enqueue(2)
      
      const first = reversePq.dequeue()
      const second = reversePq.peek()
      
      return first === 9 && // 最大值优先
             second === 5 &&
             reversePq.isValid() === true &&
             reversePq.size() === 4
    })()
  )

  console.log(
    "6. 复杂对象比较测试:",
    (() => {
      const complexPq = new PriorityQueue((a, b) => {
        // 先按年龄，再按姓名
        if (a.age !== b.age) return a.age - b.age
        return a.name.localeCompare(b.name)
      })
      
      complexPq.enqueue({ name: "Alice", age: 25 })
      complexPq.enqueue({ name: "Bob", age: 30 })
      complexPq.enqueue({ name: "Charlie", age: 25 })
      complexPq.enqueue({ name: "David", age: 20 })
      
      const first = complexPq.dequeue()
      const second = complexPq.dequeue()
      const third = complexPq.peek()
      
      return first.name === "David" && first.age === 20 &&
             second.name === "Alice" && second.age === 25 &&
             third.name === "Charlie" && third.age === 25 &&
             complexPq.isValid() === true &&
             complexPq.size() === 2
    })()
  )

  console.log(
    "7. 比较器一致性测试:",
    (() => {
      const pq1 = new PriorityQueue((a, b) => a - b)
      const pq2 = new PriorityQueue((a, b) => a - b)
      
      const values = [50, 30, 70, 20, 40, 60, 80]
      
      values.forEach(val => {
        pq1.enqueue(val)
        pq2.enqueue(val)
      })
      
      const min1 = pq1.peek()
      const min2 = pq2.peek()
      const isValid1 = pq1.isValid()
      const isValid2 = pq2.isValid()
      
      return min1 === min2 &&
             isValid1 === isValid2 &&
             isValid1 === true &&
             pq1.size() === pq2.size()
    })()
  )

  console.log(
    "8. 比较器边界测试:",
    (() => {
      const boundaryPq = new PriorityQueue((a, b) => a - b)
      
      // 测试相同值
      boundaryPq.enqueue(5)
      boundaryPq.enqueue(5)
      boundaryPq.enqueue(5)
      
      const first = boundaryPq.dequeue()
      const second = boundaryPq.peek()
      
      return first === 5 &&
             second === 5 &&
             boundaryPq.isValid() === true &&
             boundaryPq.size() === 2
    })()
  )

  console.log(
    "9. this上下文比较器测试:",
    (() => {
      const comparatorObj = {
        multiplier: 2,
        processComparator: function(values) {
          const pq = new PriorityQueue((a, b) => a - b)
          values.forEach(val => pq.enqueue(val))
          return pq.size() * this.multiplier
        }
      }
      
      const values = [10, 20, 30]
      return comparatorObj.processComparator(values) === 6 // 3*2=6
    })()
  )

  console.log(
    "10. 复杂对象this绑定比较器测试:",
    (() => {
      const comparatorConfigObj = {
        config: { threshold: 2 },
        processWithConfig: function(values) {
          const pq = new PriorityQueue((a, b) => a - b)
          values.forEach(val => pq.enqueue(val))
          return pq.size() >= this.config.threshold
        }
      }
      
      const values = [10, 20, 30]
      return comparatorConfigObj.processWithConfig(values) === true
    })()
  )

  console.log(
    "11. 比较器性能测试:",
    (() => {
      const perfPq = new PriorityQueue((a, b) => a - b)
      const iterations = 1000
      
      const start = performance.now()
      
      // 插入大量数据
      for (let i = 0; i < iterations; i++) {
        perfPq.enqueue(i)
      }
      
      // 删除所有数据
      for (let i = 0; i < iterations; i++) {
        perfPq.dequeue()
      }
      
      const end = performance.now()
      const duration = end - start
      
      return perfPq.size() === 0 &&
             perfPq.isEmpty() === true &&
             duration < 1000 &&
             duration > 0
    })()
  )

  console.log(
    "12. 比较器复杂测试:",
    (() => {
      const complexPq = new PriorityQueue((a, b) => {
        // 复杂的比较逻辑
        if (a.value !== b.value) return a.value - b.value
        if (a.priority !== b.priority) return a.priority - b.priority
        return a.id - b.id
      })
      
      complexPq.enqueue({ id: 1, value: 10, priority: 2 })
      complexPq.enqueue({ id: 2, value: 5, priority: 1 })
      complexPq.enqueue({ id: 3, value: 10, priority: 1 })
      complexPq.enqueue({ id: 4, value: 5, priority: 2 })
      
      const first = complexPq.dequeue()
      const second = complexPq.dequeue()
      const third = complexPq.peek()
      
      return first.id === 2 && first.value === 5 && first.priority === 1 &&
             second.id === 3 && second.value === 10 && second.priority === 1 &&
             third.id === 4 && third.value === 5 && third.priority === 2 &&
             complexPq.isValid() === true &&
             complexPq.size() === 2
    })()
  )
}

testPriorityQueueCustomComparator()
